#!/usr/bin/env python

import sys
import xml.dom.minidom

from DataSet import *
from Exceptions import *
from DataTransform import *


class DataPort:
    
    def _get_source_site(self):
        return self.__sourceSite
    def _set_source_site(self, sourceSite):
        self.__sourceSite = sourceSite
    def _get_target_site(self):
        return self.__targetSite
    def _set_target_site(self, targetSite):
        self.__targetSite = targetSite
    def _get_name(self):
        return self.__name
    def _set_name(self, name):
        self.__name = name
    def _get_description(self):
        return self.__description
    def _set_description(self, description):
        self.__description = description
    def _get_transforms(self):
        return self.__transforms
    
    
    source_site = property(_get_source_site, _set_source_site)
    target_site = property(_get_target_site, _set_target_site)
    name = property(_get_name, _set_name)
    description = property(_get_description, _set_description)
    transforms = property(_get_transforms)
    
    def __init__(self):
        self.__transforms = dict()
        self.target_site = None
        self.source_site = None
        
    def load_file(self, file):
        xmlDom = xml.dom.minidom.parse(file)
        self.load_xml(xmlDom)
    
    def load_xml(self, xmlDom):
        
        for sourceSiteNode in xmlDom.getElementsByTagName("source_site"):
            for node in sourceSiteNode.getElementsByTagName("DataSet"):
                self.source_site = DataSet()
                self.source_site.load_xml(node)
                break
            break
        
        # every table in source_site will have a dummy transform
        # this transform is used to process the current row
        # when iterating through the source rows.
        # Each source row will get its data loaded in to this transform
        # and the DataPort will load the transform
        for tableName in self.source_site.tables:
            table = self.source_site.tables[tableName]
            transform = DataTransform(self, self.source_site.tables[table.name])
            
            for columnName in table.schema:
                transform.outputs[columnName] = DataTransformOutput(columnName, transform)
            
            self.transforms[tableName] = transform
        
        for targetSiteNode in xmlDom.getElementsByTagName("target_site"):
            for node in targetSiteNode.getElementsByTagName("DataSet"):
                self.target_site = DataSet()
                self.target_site.load_xml(node)
                break
            
        for node in xmlDom.getElementsByTagName("transforms"):
            #pass 1: create all the needed transforms
            for childNode in node.childNodes:
                if childNode.nodeType == xml.dom.Node.ELEMENT_NODE:
                    className = childNode.tagName
                    transform = self.create_transform(className, childNode)
                    
                    self.transforms[transform.name] = transform
            
            #pass 2: hook up the transforms
            for childNode in node.childNodes:
                if childNode.nodeType == xml.dom.Node.ELEMENT_NODE:
                    transform = self.transforms[childNode.getAttribute("name")]
                    for inputNode in childNode.getElementsByTagName("DataTransformInput"):
                        inputName = inputNode.getAttribute("name")
                        sourceName = inputNode.getAttribute("source_name")
                        sourceFieldName = inputNode.getAttribute("source_field_name")
                        
                        input = transform.inputs[inputName]
                        
                        source = None
                        if sourceName in self.transforms:
                            source = self.transforms[sourceName]
                        else:
                            raise Exception("YOU SUCK!!")
                        
                        input.source = source
            break
            
        pass
    
    def save_file(self, fileUri):
        # write results of SaveXml() to fileUri
        pass
    def save_xml(self):
        #return xmlDom object of self
        pass
    
    def create_transform(self, className, xmlDom = None):
        moduleClassName = className.split(".", 2)
        
        className = moduleName = moduleClassName[0]
        if len(moduleClassName) ==2:
            className = moduleClassName[1]
            
        
        transformName = xmlDom.getAttribute("name")
        
        if className not in sys.modules:
            sys.path.append('lib/Transforms/')
            
            loadedModule = __import__(moduleName, globals(), locals(), [ className ], -1)
        else:
            loadedModule = sys.modules[className]
            
        transformClass = getattr(loadedModule, className)
        
        transform = transformClass(self, transformName)
        
        for inputNode in xmlDom.getElementsByTagName("DataTransformInput"):
            inputName = inputNode.getAttribute("name")
            if inputName not in transform.inputs:
                transform.inputs[inputName] = DataTransformInput(inputName, transform)
        
        for inputNode in xmlDom.getElementsByTagName("DataTransformOutput"):
            outputName = inputNode.getAttribute("name")
            if outputName not in transform.outputs:
                transform.outputs[inputName] = DataTransformInput(outputName, transform)
            pass
        
        return transform